package com.education.platform.api.service.impl;

import com.education.platform.api.config.ThreadUser;
import com.education.platform.api.enums.BuyBeanTypeEnum;
import com.education.platform.api.service.AccountFlowService;
import com.education.platform.api.service.PayRecordService;
import com.education.platform.api.vo.request.PayRecordUpdateVO;
import com.education.platform.common.enums.*;
import com.education.platform.common.exception.AssertException;
import com.education.platform.common.exception.BusinessException;
import com.education.platform.common.service.impl.BaseServiceImpl;
import com.education.platform.common.util.BeanUtil;
import com.education.platform.common.util.OrderNoGenerator;
import com.education.platform.dao.AccountDao;
import com.education.platform.dao.PayRecordDao;
import com.education.platform.dao.UserBaseDao;
import com.education.platform.dao.UserPointsDao;
import com.education.platform.dao.entity.AccountDO;
import com.education.platform.dao.entity.PayRecordDO;
import com.education.platform.dao.entity.UserBaseDO;
import com.education.platform.dao.entity.UserPointsDO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * describe: 支付记录
 *
 * @author : tomato
 * @date: 2020-06-21 09:35:03.389
 **/
@Service
public class PayRecordServiceImpl extends BaseServiceImpl<PayRecordDao, PayRecordDO> implements PayRecordService {

    private static final Logger LOGGER = LoggerFactory.getLogger(PayRecordServiceImpl.class);

    @Autowired
    private PayRecordDao payRecordDao;

    @Autowired
    private AccountDao accountDao;

    @Autowired
    private UserPointsDao userPointsDao;

    @Autowired
    private AccountFlowService accountFlowService;
    @Value("${vip.minCharge:1}")
    private BigDecimal minCharge;

    @Autowired
    private UserBaseDao userBaseDao;

    /**
     * 保存支付记录
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String savePayRecord(PayRecordUpdateVO updateVO) {
        this.checkPayRecord(updateVO);
        PayRecordDO recordDO = BeanUtil.convert(updateVO, PayRecordDO.class);
        recordDO.setUserId(ThreadUser.getUserId());
        recordDO.setUserName(ThreadUser.getUserName());

        recordDO.setOrderNo(OrderNoGenerator.generator());
        recordDO.setOrderStatus(OrderStatusEnum.WAIT_PAY.getValue());
        recordDO.setOrderStatusName(OrderStatusEnum.WAIT_PAY.getDes());
        recordDO.setPaymentPlatformType(updateVO.getPaymentPlatformType());
        recordDO.setCreateTime(new Date());
        recordDO.setDeleted(false);
        if (payRecordDao.insert(recordDO) != 1) {
            throw new BusinessException("创建订单失败");
        }
        return recordDO.getOrderNo();
    }


    private void checkPayRecord(PayRecordUpdateVO updateVO) {
        Integer beanNum = updateVO.getNumber();
        if (beanNum == null || beanNum <= 0) {
            AssertException.throwBusinessEp("充值失败");
        }
        if(!BuyBeanTypeEnum.checkBuyType(updateVO.getNumber(),updateVO.getTotalPrice())){
             AssertException.throwBusinessEp("充值类型不正确");
         }
    }

    /**
     * 购买豆子  支付成功
     * @param orderNo
     * @param thirdOrderNo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void paySuccess(String orderNo, String thirdOrderNo) {

        PayRecordDO query = new PayRecordDO();
        query.setOrderNo(orderNo);
        PayRecordDO order = payRecordDao.get(query);
        if(!this.checkPayBackOrder(order)){
            LOGGER.error("订单不是待支付状态，不处理支付回调");
            return;
        }

//        如果充值金额>=1   ，则设置vip , 积分状态可用
        if(minCharge.compareTo(order.getTotalPrice())<=0){
            this.setAccountVIP(order.getUserId());
            this.setPointsEnable(order.getUserId());
        }
        PayRecordDO payRecordUpdate = new PayRecordDO();
        payRecordUpdate.setOrderNo(orderNo);
        payRecordUpdate.setPaymentPlatformNo(thirdOrderNo);
        payRecordUpdate.setUpdateTime(new Date());
        payRecordUpdate.setOrderStatus(OrderStatusEnum.COMPLETE.getValue());
        payRecordUpdate.setOrderStatusName(OrderStatusEnum.COMPLETE.getDes());
        //修改为已支付
        payRecordDao.updateRecordByOrderNo(payRecordUpdate);

        PayRecordDO payRecordDO = payRecordDao.getByOrderNo(orderNo);

        AccountDO accountDO = accountDao.getByUserId(payRecordDO.getUserId());
        //账户增加豆子
        accountDao.recharge(payRecordDO.getNumber(), payRecordDO.getUserId());
        //保存流水记录
        accountFlowService.createAccountFlow(accountDO, FlowBusinessTypeEnum.BUY_BEANS, FlowTypeEnum.IN, payRecordDO.getNumber(),orderNo);

        //给邀请人送豆子
        this.rebateInviterBean(payRecordDO.getUserId());
    }

    /**
     * 给邀请人返豆子  1
     * @param userId
     */
    private void rebateInviterBean(Integer userId){
        //获取当前用户成功充值次数
        int count = payRecordDao.getSuccessCountByUserId(userId);
        //不是第一次充值，返回
        if(count > 1){
            return;
        }
        //获取当前用户是否  有邀请人
        UserBaseDO user = userBaseDao.getById(userId);
        if(user.getInviter()!=null){
            //获取邀请人
            UserBaseDO inviter =  userBaseDao.getById(user.getInviter());
            if(inviter!=null){
                //邀请人账户 增加一个豆子
                AccountDO inviterAccount = accountDao.getByUserId(inviter.getId());
                accountDao.recharge(1,inviter.getId());
                //保存流水记录
                accountFlowService.createAccountFlow(inviterAccount, FlowBusinessTypeEnum.REBATE_BEANS, FlowTypeEnum.IN, 1,"");
            }
        }
    }

    /**
     * 设置账户为vip
     */
    private void setAccountVIP(Integer userId){
        AccountDO accountDO = accountDao.getByUserId(userId);
        if(accountDO == null){
          throw new BusinessException("账户异常！");
        }
        if(MemberTypeEnum.VIP.getValue().equals(accountDO.getMemberType())){
            return;
        }
        AccountDO accountUpdate = new AccountDO();
        accountUpdate.setId(accountDO.getId());
        accountUpdate.setMemberType(MemberTypeEnum.VIP.getValue());
        accountDao.updateById(accountUpdate);
    }

    /**
     * 设置积分状态可用
     */
    private void setPointsEnable(Integer userId){
        UserPointsDO query = new UserPointsDO();
        query.setUserId(userId);
        query.setDeleted(false);
        UserPointsDO userPointsDO = userPointsDao.get(query);
        if(userPointsDO != null && !userPointsDO.getStatus()){
            UserPointsDO update = new UserPointsDO();
            update.setStatus(true);
            update.setId(userPointsDO.getId());
            userPointsDao.updateById(update);
        }
    }

    /**
     *检查
     * @param
     * @return
     */
    private boolean checkPayBackOrder(PayRecordDO order) {

        if (order != null) {
            Integer status = order.getOrderStatus();
            if (OrderStatusEnum.WAIT_PAY.getValue().equals(status)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 内购 购买豆子

     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void iapPayRecord( PayRecordDO recordDO ) {
        if(recordDO.getTotalPrice()==null||recordDO.getNumber()==null){
            throw new BusinessException("数据异常！");
        }
        PayRecordDO query =  new PayRecordDO();
        query.setPaymentPlatformNo(recordDO.getPaymentPlatformNo());
        PayRecordDO exist = payRecordDao.get(query);
        if(exist!=null){
            throw new BusinessException("当前交易失效！");
        }
        recordDO.setUserId(ThreadUser.getUserId());
        recordDO.setUserName(ThreadUser.getUserName());
        recordDO.setOrderNo(OrderNoGenerator.generator());
        //状态  已完成
        recordDO.setOrderStatus(OrderStatusEnum.COMPLETE.getValue());
        recordDO.setOrderStatusName(OrderStatusEnum.COMPLETE.getDes());
        //支付方式  iap
        recordDO.setPaymentPlatformType(PaymentTypeEnum.IAP.getValue());
        recordDO.setCreateTime(new Date());
        recordDO.setPayTime(new Date());
        recordDO.setDeleted(false);
        if (payRecordDao.insert(recordDO) != 1) {
            throw new BusinessException("创建订单失败");
        }

        AccountDO accountDO = accountDao.getByUserId(recordDO.getUserId());
        //账户增加豆子
        accountDao.recharge(recordDO.getNumber(), recordDO.getUserId());
        //保存流水记录
        accountFlowService.createAccountFlow(accountDO, FlowBusinessTypeEnum.BUY_BEANS, FlowTypeEnum.IN, recordDO.getNumber(),recordDO.getOrderNo());

        //        如果充值金额>=1   ，则设置vip , 积分状态可用
        if(minCharge.compareTo(recordDO.getTotalPrice())<=0){
            this.setAccountVIP(recordDO.getUserId());
            this.setPointsEnable(recordDO.getUserId());
        }
        //给邀请人送豆子
        this.rebateInviterBean(recordDO.getUserId());
    }
}
